diff --git a/package.json b/package.json index 590af7ccfe..9fd0d8c331 100644 --- a/package.json +++ b/package.json @@ -14,15 +14,20 @@ "@solana/web3.js": "1.73.2", "@types/bn.js": "5.1.6", "@types/chai": "5.0.0", + "@types/glob": "^8.1.0", "@types/mocha": "8.2.3", "@typescript-eslint/eslint-plugin": "4.33.0", "@typescript-eslint/parser": "4.33.0", + "bs58": "^6.0.0", "chai": "4.4.1", "eslint": "7.32.0", "eslint-config-prettier": "8.3.0", "eslint-plugin-prettier": "3.4.0", + "glob": "^11.0.0", "husky": "7.0.4", + "mocha": "^11.0.1", "prettier": "3.0.1", + "ts-mocha": "^10.0.0", "typedoc": "0.23.23", "typescript": "4.9.5", "@pythnetwork/price-service-client": "1.9.0" diff --git a/programs/drift/src/error.rs b/programs/drift/src/error.rs index 5c2d229ab3..0cc98b1657 100644 --- a/programs/drift/src/error.rs +++ b/programs/drift/src/error.rs @@ -621,6 +621,12 @@ pub enum ErrorCode { InvalidPythLazerMessage, #[msg("Pyth lazer message does not correspond to correct fed id")] PythLazerMessagePriceFeedMismatch, + #[msg("FailedZerofiCPI")] + FailedZerofiCPI, + #[msg("InvalidZerofiProgram")] + InvalidZerofiProgram, + #[msg("InvalidZerofiMarket")] + InvalidZerofiMarket, } #[macro_export] diff --git a/programs/drift/src/instructions/admin.rs b/programs/drift/src/instructions/admin.rs index 7fad00f109..e57af7c00d 100644 --- a/programs/drift/src/instructions/admin.rs +++ b/programs/drift/src/instructions/admin.rs @@ -41,6 +41,7 @@ use crate::state::fulfillment_params::phoenix::PhoenixMarketContext; use crate::state::fulfillment_params::phoenix::PhoenixV1FulfillmentConfig; use crate::state::fulfillment_params::serum::SerumContext; use crate::state::fulfillment_params::serum::SerumV3FulfillmentConfig; +use crate::state::fulfillment_params::zerofi::{ZerofiContext, ZerofiFulfillmentConfig}; use crate::state::high_leverage_mode_config::HighLeverageModeConfig; use crate::state::insurance_fund_stake::ProtocolIfSharesTransferConfig; use crate::state::oracle::get_sb_on_demand_price; @@ -631,6 +632,62 @@ pub fn handle_update_phoenix_fulfillment_config_status( Ok(()) } +pub fn handle_initialize_zerofi_fulfillment_config( + ctx: Context, + market_index: u16, +) -> Result<()> { + validate!( + market_index != QUOTE_SPOT_MARKET_INDEX, + ErrorCode::InvalidSpotMarketAccount, + "Cannot add zerofi market to quote asset" + )?; + + let base_spot_market = load!(&ctx.accounts.base_spot_market)?; + let quote_spot_market = load!(&ctx.accounts.quote_spot_market)?; + + let zerofi_program_id = crate::state::fulfillment_params::zerofi::zerofi_program_id::id(); + + validate!( + ctx.accounts.zerofi_program.key() == zerofi_program_id, + ErrorCode::InvalidZerofiProgram + )?; + + let zerofi_market_context = ZerofiContext { + zerofi_program: &ctx.accounts.zerofi_program, + zerofi_market: &ctx.accounts.zerofi_market, + }; + + // Validates owner and discriminator + let market = zerofi_market_context.load_zerofi_market()?; + + validate!( + market.mint_base == base_spot_market.mint, + ErrorCode::InvalidZerofiMarket, + "Invalid base mint" + )?; + validate!( + market.mint_quote == quote_spot_market.mint, + ErrorCode::InvalidZerofiMarket, + "Invalid quote mint" + )?; + + let zerofi_fulfillment_config_key = ctx.accounts.zerofi_fulfillment_config.key(); + let mut zerofi_fulfillment_config = ctx.accounts.zerofi_fulfillment_config.load_init()?; + *zerofi_fulfillment_config = zerofi_market_context + .to_zerofi_fulfillment_config(&zerofi_fulfillment_config_key, market_index)?; + Ok(()) +} + +pub fn handle_update_zerofi_fulfillment_config_status( + ctx: Context, + status: SpotFulfillmentConfigStatus, +) -> Result<()> { + let mut config = load_mut!(ctx.accounts.zerofi_fulfillment_config)?; + msg!("config.status {:?} -> {:?}", config.status, status); + config.status = status; + Ok(()) +} + pub fn handle_initialize_perp_market( ctx: Context, market_index: u16, @@ -4457,6 +4514,59 @@ pub struct UpdatePhoenixFulfillmentConfig<'info> { pub admin: Signer<'info>, } +#[derive(Accounts)] +#[instruction(market_index: u16)] +pub struct InitializeZerofiFulfillmentConfig<'info> { + #[account( + seeds = [b"spot_market", market_index.to_le_bytes().as_ref()], + bump, + )] + pub base_spot_market: AccountLoader<'info, SpotMarket>, + #[account( + seeds = [b"spot_market", 0_u16.to_le_bytes().as_ref()], + bump, + )] + pub quote_spot_market: AccountLoader<'info, SpotMarket>, + #[account( + mut, + has_one = admin + )] + pub state: Box>, + /// CHECK: single valid pubkey checked in ix + pub zerofi_program: AccountInfo<'info>, + /// CHECK: owner and discriminator checked in ix + pub zerofi_market: AccountInfo<'info>, + #[account( + constraint = state.signer.eq(&drift_signer.key()) + )] + /// CHECK: program signer + pub drift_signer: AccountInfo<'info>, + #[account( + init, + seeds = [b"zerofi_fulfillment_config".as_ref(), zerofi_market.key.as_ref()], + space = ZerofiFulfillmentConfig::SIZE, + bump, + payer = admin, + )] + pub zerofi_fulfillment_config: AccountLoader<'info, ZerofiFulfillmentConfig>, + #[account(mut)] + pub admin: Signer<'info>, + pub rent: Sysvar<'info, Rent>, + pub system_program: Program<'info, System>, +} + +#[derive(Accounts)] +pub struct UpdateZerofiFulfillmentConfig<'info> { + #[account( + has_one = admin + )] + pub state: Box>, + #[account(mut)] + pub zerofi_fulfillment_config: AccountLoader<'info, ZerofiFulfillmentConfig>, + #[account(mut)] + pub admin: Signer<'info>, +} + #[derive(Accounts)] pub struct UpdateSerumVault<'info> { #[account( diff --git a/programs/drift/src/instructions/keeper.rs b/programs/drift/src/instructions/keeper.rs index 8685c6380a..06a8693a99 100644 --- a/programs/drift/src/instructions/keeper.rs +++ b/programs/drift/src/instructions/keeper.rs @@ -37,6 +37,7 @@ use crate::state::fulfillment_params::drift::MatchFulfillmentParams; use crate::state::fulfillment_params::openbook_v2::OpenbookV2FulfillmentParams; use crate::state::fulfillment_params::phoenix::PhoenixFulfillmentParams; use crate::state::fulfillment_params::serum::SerumFulfillmentParams; +use crate::state::fulfillment_params::zerofi::ZerofiFulfillmentParams; use crate::state::high_leverage_mode_config::HighLeverageModeConfig; use crate::state::insurance_fund_stake::InsuranceFundStake; use crate::state::oracle_map::OracleMap; @@ -186,6 +187,7 @@ pub enum SpotFulfillmentType { Match, PhoenixV1, OpenbookV2, + Zerofi, } #[access_control( @@ -283,6 +285,17 @@ fn fill_spot_order<'c: 'info, 'info>( clock.unix_timestamp, )?) } + SpotFulfillmentType::Zerofi => { + let base_market = spot_market_map.get_ref(&market_index)?; + let quote_market = spot_market_map.get_quote_spot_market()?; + Box::new(ZerofiFulfillmentParams::new( + remaining_accounts_iter, + &ctx.accounts.state, + &base_market, + "e_market, + clock.unix_timestamp, + )?) + } SpotFulfillmentType::Match => { let base_market = spot_market_map.get_ref(&market_index)?; let quote_market = spot_market_map.get_quote_spot_market()?; diff --git a/programs/drift/src/instructions/user.rs b/programs/drift/src/instructions/user.rs index 90e579fb3a..c0178f3a37 100644 --- a/programs/drift/src/instructions/user.rs +++ b/programs/drift/src/instructions/user.rs @@ -52,6 +52,7 @@ use crate::state::fulfillment_params::drift::MatchFulfillmentParams; use crate::state::fulfillment_params::openbook_v2::OpenbookV2FulfillmentParams; use crate::state::fulfillment_params::phoenix::PhoenixFulfillmentParams; use crate::state::fulfillment_params::serum::SerumFulfillmentParams; +use crate::state::fulfillment_params::zerofi::ZerofiFulfillmentParams; use crate::state::high_leverage_mode_config::HighLeverageModeConfig; use crate::state::oracle::StrictOraclePrice; use crate::state::order_params::RFQMatch; @@ -1747,6 +1748,17 @@ pub fn handle_place_and_take_spot_order<'c: 'info, 'info>( clock.unix_timestamp, )?) } + SpotFulfillmentType::Zerofi => { + let base_market = spot_market_map.get_ref(&market_index)?; + let quote_market = spot_market_map.get_quote_spot_market()?; + Box::new(ZerofiFulfillmentParams::new( + remaining_accounts_iter, + &ctx.accounts.state, + &base_market, + "e_market, + clock.unix_timestamp, + )?) + } SpotFulfillmentType::Match => { let base_market = spot_market_map.get_ref(&market_index)?; let quote_market = spot_market_map.get_quote_spot_market()?; @@ -1895,6 +1907,17 @@ pub fn handle_place_and_make_spot_order<'c: 'info, 'info>( clock.unix_timestamp, )?) } + SpotFulfillmentType::Zerofi => { + let base_market = spot_market_map.get_ref(&market_index)?; + let quote_market = spot_market_map.get_quote_spot_market()?; + Box::new(ZerofiFulfillmentParams::new( + remaining_accounts_iter, + &ctx.accounts.state, + &base_market, + "e_market, + clock.unix_timestamp, + )?) + } SpotFulfillmentType::Match => { let base_market = spot_market_map.get_ref(&market_index)?; let quote_market = spot_market_map.get_quote_spot_market()?; diff --git a/programs/drift/src/lib.rs b/programs/drift/src/lib.rs index cde40ba8d0..44510d94ab 100644 --- a/programs/drift/src/lib.rs +++ b/programs/drift/src/lib.rs @@ -813,6 +813,7 @@ pub mod drift { ) -> Result<()> { handle_update_openbook_v2_fulfillment_config_status(ctx, status) } + pub fn initialize_phoenix_fulfillment_config( ctx: Context, market_index: u16, @@ -827,6 +828,20 @@ pub mod drift { handle_update_phoenix_fulfillment_config_status(ctx, status) } + pub fn initialize_zerofi_fulfillment_config( + ctx: Context, + market_index: u16, + ) -> Result<()> { + handle_initialize_zerofi_fulfillment_config(ctx, market_index) + } + + pub fn zerofi_fulfillment_config_status( + ctx: Context, + status: SpotFulfillmentConfigStatus, + ) -> Result<()> { + handle_update_zerofi_fulfillment_config_status(ctx, status) + } + pub fn update_serum_vault(ctx: Context) -> Result<()> { handle_update_serum_vault(ctx) } diff --git a/programs/drift/src/state/events.rs b/programs/drift/src/state/events.rs index c94150bf92..ba0ea7fbd9 100644 --- a/programs/drift/src/state/events.rs +++ b/programs/drift/src/state/events.rs @@ -345,6 +345,7 @@ pub enum OrderActionExplanation { OrderFilledWithLPJit, DeriskLp, OrderFilledWithOpenbookV2, + OrderFilledWithZerofi, } #[event] diff --git a/programs/drift/src/state/fulfillment_params/mod.rs b/programs/drift/src/state/fulfillment_params/mod.rs index dc1fae2416..13960d64a2 100644 --- a/programs/drift/src/state/fulfillment_params/mod.rs +++ b/programs/drift/src/state/fulfillment_params/mod.rs @@ -2,3 +2,4 @@ pub mod drift; pub mod openbook_v2; pub mod phoenix; pub mod serum; +pub mod zerofi; diff --git a/programs/drift/src/state/fulfillment_params/zerofi.rs b/programs/drift/src/state/fulfillment_params/zerofi.rs new file mode 100644 index 0000000000..486d940776 --- /dev/null +++ b/programs/drift/src/state/fulfillment_params/zerofi.rs @@ -0,0 +1,488 @@ +#![allow(unused)] // unused when target_os is not solana +use crate::controller::position::PositionDirection; +use crate::error::{DriftResult, ErrorCode}; +use crate::instructions::SpotFulfillmentType; +use crate::math::casting::Cast; +use crate::math::constants::PRICE_TO_QUOTE_PRECISION_RATIO; +use crate::math::orders::{standardize_base_asset_amount, standardize_base_asset_amount_ceil}; +use crate::math::safe_math::SafeMath; +use crate::math::serum::{ + calculate_price_from_serum_limit_price, calculate_serum_limit_price, + calculate_serum_max_coin_qty, +}; +use crate::math::spot_withdraw::validate_spot_market_vault_amount; +use crate::signer::get_signer_seeds; +use crate::state::events::OrderActionExplanation; +use crate::state::load_ref::load_ref; +use crate::state::spot_fulfillment_params::{ExternalSpotFill, SpotFulfillmentParams}; +use crate::state::spot_market::{SpotBalanceType, SpotFulfillmentConfigStatus, SpotMarket}; +use crate::state::state::State; +use crate::state::traits::Size; +use crate::{load, load_mut, validate}; +use anchor_lang::prelude::*; +use anchor_lang::prelude::{Account, Program, System}; +use anchor_lang::{account, Discriminator, InstructionData, Key}; +use anchor_spl::token::{Token, TokenAccount}; +use arrayref::array_ref; +use solana_program::account_info::AccountInfo; +use solana_program::instruction::{AccountMeta, Instruction}; +use solana_program::program::invoke_signed_unchecked; +use solana_program::pubkey::Pubkey; +use std::cell::Ref; +use std::convert::TryFrom; + +pub mod zerofi_program_id { + anchor_lang::declare_id!("ZERor4xhbUycZ6gb9ntrhqscUcZmAbQDjEAtCf4hbZY"); +} + +#[account(zero_copy(unsafe))] +#[derive(Default, PartialEq, Eq, Debug)] +#[repr(C)] +pub struct ZerofiFulfillmentConfig { + pub pubkey: Pubkey, // 32 + pub zerofi_program_id: Pubkey, // 64 + pub zerofi_market: Pubkey, // 96 + pub zerofi_vault_base: Pubkey, // 128 + pub zerofi_vault_base_info: Pubkey, // 160 + pub zerofi_vault_quote: Pubkey, // 192 + pub zerofi_vault_quote_info: Pubkey, // 224 + pub market_index: u16, // 256 + pub fulfillment_type: SpotFulfillmentType, // 258 + pub status: SpotFulfillmentConfigStatus, // 259 + pub padding: [u8; 4], // 260 +} + +impl Size for ZerofiFulfillmentConfig { + const SIZE: usize = 264; +} + +pub struct ZerofiContext<'a, 'b> { + pub zerofi_program: &'a AccountInfo<'b>, + pub zerofi_market: &'a AccountInfo<'b>, +} + +#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] +#[repr(C)] +pub struct ZerofiMarket { + pub discriminator: u64, + pub _config_authority: Pubkey, + pub _update_authority: Pubkey, + pub mint_base: Pubkey, + pub mint_quote: Pubkey, + pub vault_base: Pubkey, + pub vault_base_info: Pubkey, + pub vault_quote: Pubkey, + pub vault_quote_info: Pubkey, +} + +impl ZerofiMarket { + pub fn load_ref<'a>(account_info: &'a AccountInfo) -> Result> { + use anchor_lang::error::ErrorCode; + validate!( + account_info.owner == &zerofi_program_id::ID, + ErrorCode::AccountOwnedByWrongProgram + )?; + let data = account_info.try_borrow_data()?; + let market: Ref = Ref::map(data, |data| { + bytemuck::from_bytes(&data[..std::mem::size_of::()]) + }); + validate!( + market.discriminator == 4, + ErrorCode::AccountDiscriminatorMismatch + )?; + Ok(market) + } +} + +impl<'a, 'b> ZerofiContext<'a, 'b> { + pub fn load_zerofi_market(&self) -> DriftResult> { + let market = + ZerofiMarket::load_ref(self.zerofi_market).map_err(|_| ErrorCode::FailedZerofiCPI)?; + Ok(market) + } + + pub fn to_zerofi_fulfillment_config( + &self, + zerofi_fulfillment_config_key: &Pubkey, + market_index: u16, + ) -> DriftResult { + let market = self + .load_zerofi_market() + .map_err(|_| ErrorCode::FailedZerofiCPI)?; + Ok(ZerofiFulfillmentConfig { + pubkey: *zerofi_fulfillment_config_key, + zerofi_program_id: *self.zerofi_program.key, + zerofi_market: *self.zerofi_market.key, + zerofi_vault_base: market.vault_base, + zerofi_vault_base_info: market.vault_base_info, + zerofi_vault_quote: market.vault_quote, + zerofi_vault_quote_info: market.vault_quote_info, + market_index, + fulfillment_type: SpotFulfillmentType::Zerofi, + status: SpotFulfillmentConfigStatus::Enabled, + padding: [0; 4], + }) + } +} + +pub struct ZerofiFulfillmentParams<'a, 'b> { + pub drift_signer: &'a AccountInfo<'b>, // same as penalty payer + pub zerofi_context: ZerofiContext<'a, 'b>, + pub zerofi_vault_base: &'a AccountInfo<'b>, + pub zerofi_vault_base_info: &'a AccountInfo<'b>, + pub zerofi_vault_quote: &'a AccountInfo<'b>, + pub zerofi_vault_quote_info: &'a AccountInfo<'b>, + pub base_market_vault: Box>, + pub quote_market_vault: Box>, + pub token_program: Program<'b, Token>, + pub instructions_sysvar: &'a AccountInfo<'b>, + pub signer_nonce: u8, + pub now: i64, + pub base_precision: u64, + pub base_step_size: u64, +} + +impl<'a, 'b> ZerofiFulfillmentParams<'a, 'b> { + #[allow(clippy::type_complexity)] + pub fn new<'c: 'b>( + account_info_iter: &'a mut std::iter::Peekable>>, + state: &State, + base_market: &SpotMarket, + quote_market: &SpotMarket, + now: i64, + ) -> DriftResult { + let account_info_vec = account_info_iter.collect::>(); + let account_infos = array_ref![account_info_vec, 0, 12]; + let [zerofi_fulfillment_config, drift_signer, zerofi_program, zerofi_market, zerofi_vault_base_info, zerofi_vault_quote_info, zerofi_vault_base, zerofi_vault_quote, base_market_vault, quote_market_vault, token_program, instructions_sysvar] = + account_infos; + + validate!( + &state.signer == drift_signer.key, + ErrorCode::InvalidFulfillmentConfig + )?; + validate!( + &base_market.vault == base_market_vault.key, + ErrorCode::InvalidFulfillmentConfig + )?; + validate!( + "e_market.vault == quote_market_vault.key, + ErrorCode::InvalidFulfillmentConfig + )?; + + let zerofi_fulfillment_config_loader: AccountLoader = + AccountLoader::try_from(zerofi_fulfillment_config).map_err(|e| { + msg!("{:?}", e); + ErrorCode::InvalidFulfillmentConfig + })?; + let zerofi_fulfillment_config = load!(zerofi_fulfillment_config_loader)?; + + validate!( + zerofi_fulfillment_config.market_index == base_market.market_index, + ErrorCode::InvalidFulfillmentConfig, + "config market index {} does not equal base asset index {}", + zerofi_fulfillment_config.market_index, + base_market.market_index + )?; + + validate!( + zerofi_market.key == &zerofi_fulfillment_config.zerofi_market, + ErrorCode::InvalidFulfillmentConfig, + "Zerofi market key does not match" + )?; + + // loading market data, validating discriminator + let market = + ZerofiMarket::load_ref(zerofi_market).map_err(|_| ErrorCode::FailedZerofiCPI)?; + + validate!( + zerofi_fulfillment_config.status == SpotFulfillmentConfigStatus::Enabled, + ErrorCode::SpotFulfillmentConfigDisabled + )?; + + validate!( + &zerofi_fulfillment_config.zerofi_program_id == zerofi_market.owner, + ErrorCode::FailedZerofiCPI, + "market owner {} needs to be equal to {}!", + zerofi_market.owner, + zerofi_fulfillment_config.zerofi_program_id + ); + validate!( + &zerofi_fulfillment_config.zerofi_program_id == zerofi_program.key, + ErrorCode::InvalidFulfillmentConfig + )?; + + validate!( + &market.vault_base_info == zerofi_vault_base_info.key, + ErrorCode::InvalidFulfillmentConfig, + "Zerofi vault info base key does not match" + )?; + + validate!( + &market.vault_quote_info == zerofi_vault_quote_info.key, + ErrorCode::InvalidFulfillmentConfig, + "Zerofi vault info quote key does not match" + )?; + + validate!( + &market.vault_base == zerofi_vault_base.key, + ErrorCode::InvalidFulfillmentConfig, + "Zerofi quote vault key does not match" + )?; + + validate!( + &market.vault_quote == zerofi_vault_quote.key, + ErrorCode::InvalidFulfillmentConfig, + "Zerofi quote vault key does not match" + )?; + + let base_market_vault: Box> = + Box::new(Account::try_from(base_market_vault).map_err(|e| { + msg!("{:?}", e); + ErrorCode::InvalidFulfillmentConfig + })?); + let quote_market_vault: Box> = + Box::new(Account::try_from(quote_market_vault).map_err(|e| { + msg!("{:?}", e); + ErrorCode::InvalidFulfillmentConfig + })?); + + validate!( + market.mint_quote == quote_market_vault.mint, + ErrorCode::InvalidFulfillmentConfig + )?; + validate!( + market.mint_base == base_market_vault.mint, + ErrorCode::InvalidFulfillmentConfig + )?; + + let token_program: Program = Program::try_from(*token_program).map_err(|e| { + msg!("{:?}", e); + ErrorCode::InvalidFulfillmentConfig + })?; + validate!( + instructions_sysvar.key == &solana_program::sysvar::instructions::ID, + ErrorCode::InvalidFulfillmentConfig + )?; + Ok(ZerofiFulfillmentParams { + drift_signer, + zerofi_context: ZerofiContext { + zerofi_program, + zerofi_market, + }, + zerofi_vault_base_info, + zerofi_vault_quote_info, + zerofi_vault_base, + zerofi_vault_quote, + base_market_vault, + quote_market_vault, + token_program, + instructions_sysvar, + signer_nonce: state.signer_nonce, + now, + base_precision: base_market.get_precision(), + base_step_size: base_market.order_step_size, + }) + } +} + +impl<'a, 'b> ZerofiFulfillmentParams<'a, 'b> { + pub fn invoke_swap(&self, is_base_to_quote: bool, data: Vec) -> DriftResult { + let ctx = &self.zerofi_context; + let accounts = if is_base_to_quote { + vec![ + AccountMeta::new(*ctx.zerofi_market.key, false), + AccountMeta::new(*self.zerofi_vault_base_info.key, false), + AccountMeta::new(*self.zerofi_vault_base.key, false), + AccountMeta::new(*self.zerofi_vault_quote_info.key, false), + AccountMeta::new(*self.zerofi_vault_quote.key, false), + AccountMeta::new(self.base_market_vault.key(), false), + AccountMeta::new(self.quote_market_vault.key(), false), + AccountMeta::new(*self.drift_signer.key, true), + AccountMeta::new_readonly(*self.token_program.key, false), + AccountMeta::new_readonly(*self.instructions_sysvar.key, false), + ] + } else { + vec![ + AccountMeta::new(*ctx.zerofi_market.key, false), + AccountMeta::new(*self.zerofi_vault_quote_info.key, false), + AccountMeta::new(*self.zerofi_vault_quote.key, false), + AccountMeta::new(*self.zerofi_vault_base_info.key, false), + AccountMeta::new(*self.zerofi_vault_base.key, false), + AccountMeta::new(self.quote_market_vault.key(), false), + AccountMeta::new(self.base_market_vault.key(), false), + AccountMeta::new(*self.drift_signer.key, true), + AccountMeta::new_readonly(*self.token_program.key, false), + AccountMeta::new_readonly(*self.instructions_sysvar.key, false), + ] + }; + let account_infos = vec![ + ctx.zerofi_program.clone(), + ctx.zerofi_market.clone(), + self.zerofi_vault_base_info.clone(), + self.zerofi_vault_base.clone(), + self.zerofi_vault_quote_info.clone(), + self.zerofi_vault_quote.clone(), + self.base_market_vault.to_account_info(), + self.quote_market_vault.to_account_info(), + self.drift_signer.clone(), + self.token_program.to_account_info(), + self.instructions_sysvar.to_account_info(), + ]; + let swap_instruction = Instruction { + program_id: *ctx.zerofi_program.key, + accounts, + data, + }; + let signer_seeds = get_signer_seeds(&self.signer_nonce); + let signers_seeds = &[&signer_seeds[..]]; + + invoke_signed_unchecked(&swap_instruction, &account_infos, signers_seeds).map_err(|e| { + msg!("{:?}", e); + ErrorCode::FailedZerofiCPI + })?; + + Ok(()) + } +} + +impl<'a, 'b> SpotFulfillmentParams for ZerofiFulfillmentParams<'a, 'b> { + fn is_external(&self) -> bool { + true + } + fn fulfill_order( + &mut self, + taker_direction: PositionDirection, + taker_price: u64, + taker_base_asset_amount: u64, + taker_max_quote_asset_amount: u64, + ) -> DriftResult { + let market = self.zerofi_context.load_zerofi_market()?; + + // According to calculate_fill_price(), this is how taker_price works + let taker_quote_asset_amount: u64 = taker_base_asset_amount + .cast::()? + .safe_mul(taker_price.cast()?)? + .safe_div(self.base_precision.cast()?)? + .cast::()?; + + // Convert the max_quote limitation to max_base using taker_price + let taker_max_base_asset_amount: u64 = taker_max_quote_asset_amount + .cast::()? + .safe_mul(self.base_precision.cast()?)? + .safe_div(taker_price.cast()?)? + .cast::()?; + + let is_base_to_quote = taker_direction == PositionDirection::Short; + let (in_amount, out_amount) = if !is_base_to_quote { + let max_quote_in = taker_quote_asset_amount.min(taker_max_quote_asset_amount); + (max_quote_in, taker_base_asset_amount) + } else { + let max_base_in = taker_base_asset_amount.min(taker_max_base_asset_amount); + (max_base_in, taker_quote_asset_amount) + }; + + let mut args = vec![0u8; 17]; + args[0] = 6; + args[1..9].copy_from_slice(&in_amount.to_le_bytes()); + args[9..17].copy_from_slice(&out_amount.to_le_bytes()); + + let base_before = self.base_market_vault.amount; + let quote_before = self.quote_market_vault.amount; + + self.invoke_swap(is_base_to_quote, args)?; + + self.base_market_vault.reload().map_err(|_e| { + msg!("Failed to reload base_market_vault"); + ErrorCode::FailedZerofiCPI + })?; + self.quote_market_vault.reload().map_err(|_e| { + msg!("Failed to reload quote_market_vault"); + ErrorCode::FailedZerofiCPI + })?; + + let base_after = self.base_market_vault.amount; + let quote_after = self.quote_market_vault.amount; + + // Forcing the step size will make the fill have a slightly worse price, + // with the extra tokens being left on the base market vault. + let (base_update_direction, base_asset_amount_filled) = if base_after > base_before { + ( + SpotBalanceType::Deposit, + standardize_base_asset_amount( + base_after.safe_sub(base_before)?, + self.base_step_size, + )?, + ) + } else { + ( + SpotBalanceType::Borrow, + standardize_base_asset_amount_ceil( + base_before.safe_sub(base_after)?, + self.base_step_size, + )?, + ) + }; + + if base_asset_amount_filled == 0 { + msg!("No base filled on zerofi"); + return Ok(ExternalSpotFill::empty()); + } + + let (quote_update_direction, quote_asset_amount_filled) = + if base_update_direction == SpotBalanceType::Borrow { + let quote_asset_amount_delta = quote_after.safe_sub(quote_before)?; + (SpotBalanceType::Deposit, quote_asset_amount_delta) + } else { + let quote_asset_amount_delta = quote_before.safe_sub(quote_after)?; + (SpotBalanceType::Borrow, quote_asset_amount_delta) + }; + + Ok(ExternalSpotFill { + base_asset_amount_filled, + quote_asset_amount_filled, + base_update_direction, + quote_update_direction, + fee: 0, + unsettled_referrer_rebate: 0, + settled_referrer_rebate: 0, + }) + } + + fn get_best_bid_and_ask(&self) -> DriftResult<(Option, Option)> { + Ok((None, None)) + } + + fn get_order_action_explanation(&self) -> DriftResult { + Ok(OrderActionExplanation::OrderFilledWithZerofi) + } + + fn validate_vault_amounts( + &self, + base_market: &Ref, + quote_market: &Ref, + ) -> DriftResult { + validate_spot_market_vault_amount(base_market, self.base_market_vault.amount)?; + validate_spot_market_vault_amount(quote_market, self.quote_market_vault.amount)?; + Ok(()) + } + + fn validate_markets( + &self, + base_market: &SpotMarket, + quote_market: &SpotMarket, + ) -> DriftResult<()> { + validate!( + self.base_market_vault.mint == base_market.mint, + ErrorCode::DefaultError, + "base mints dont match" + )?; + + validate!( + self.quote_market_vault.mint == quote_market.mint, + ErrorCode::DefaultError, + "base mints dont match" + )?; + + Ok(()) + } +} diff --git a/sdk/src/addresses/pda.ts b/sdk/src/addresses/pda.ts index 793ade9c77..6c8a0dacd3 100644 --- a/sdk/src/addresses/pda.ts +++ b/sdk/src/addresses/pda.ts @@ -271,6 +271,19 @@ export function getOpenbookV2FulfillmentConfigPublicKey( )[0]; } +export function getZerofiFulfillmentConfigPublicKey( + programId: PublicKey, + market: PublicKey +): PublicKey { + return PublicKey.findProgramAddressSync( + [ + Buffer.from(anchor.utils.bytes.utf8.encode('zerofi_fulfillment_config')), + market.toBuffer(), + ], + programId + )[0]; +} + export function getReferrerNamePublicKeySync( programId: PublicKey, nameBuffer: number[] diff --git a/sdk/src/adminClient.ts b/sdk/src/adminClient.ts index dde5aea08f..ce71650d25 100644 --- a/sdk/src/adminClient.ts +++ b/sdk/src/adminClient.ts @@ -35,6 +35,7 @@ import { getHighLeverageModeConfigPublicKey, getPythLazerOraclePublicKey, getProtectedMakerModeConfigPublicKey, + getZerofiFulfillmentConfigPublicKey, } from './addresses/pda'; import { squareRootBN } from './math/utils'; import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; @@ -57,6 +58,10 @@ const OPENBOOK_PROGRAM_ID = new PublicKey( 'opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb' ); +const ZEROFI_PROGRAM_ID = new PublicKey( + 'ZERor4xhbUycZ6gb9ntrhqscUcZmAbQDjEAtCf4hbZY' +); + export class AdminClient extends DriftClient { public async initialize( usdcMint: PublicKey, @@ -442,6 +447,52 @@ export class AdminClient extends DriftClient { ); } + public async initializeZerofiFulfillmentConfig( + marketIndex: number, + zerofiMarket: PublicKey + ): Promise { + const initializeIx = await this.getInitializeZerofiFulfillmentConfigIx( + marketIndex, + zerofiMarket + ); + + const tx = await this.buildTransaction(initializeIx); + + const { txSig } = await this.sendTransaction(tx, [], this.opts); + + return txSig; + } + + public async getInitializeZerofiFulfillmentConfigIx( + marketIndex: number, + zerofiMarket: PublicKey + ): Promise { + const zerofiFulfillmentConfig = getZerofiFulfillmentConfigPublicKey( + this.program.programId, + zerofiMarket + ); + + return this.program.instruction.initializeZerofiFulfillmentConfig( + marketIndex, + { + accounts: { + baseSpotMarket: this.getSpotMarketAccount(marketIndex).pubkey, + quoteSpotMarket: this.getQuoteSpotMarketAccount().pubkey, + state: await this.getStatePublicKey(), + zerofiProgram: ZEROFI_PROGRAM_ID, + zerofiMarket: zerofiMarket, + driftSigner: this.getSignerPublicKey(), + zerofiFulfillmentConfig: zerofiFulfillmentConfig, + admin: this.isSubscribed + ? this.getStateAccount().admin + : this.wallet.publicKey, + rent: SYSVAR_RENT_PUBKEY, + systemProgram: anchor.web3.SystemProgram.programId, + }, + } + ); + } + public async initializePerpMarket( marketIndex: number, priceOracle: PublicKey, diff --git a/sdk/src/driftClient.ts b/sdk/src/driftClient.ts index fa19604d90..e6def3e194 100644 --- a/sdk/src/driftClient.ts +++ b/sdk/src/driftClient.ts @@ -58,6 +58,7 @@ import { TxParams, UserAccount, UserStatsAccount, + ZerofiFulfillmentConfigAccount, } from './types'; import driftIDL from './idl/drift.json'; @@ -104,6 +105,7 @@ import { getUserAccountPublicKey, getUserAccountPublicKeySync, getUserStatsAccountPublicKey, + getZerofiFulfillmentConfigPublicKey, } from './addresses/pda'; import { DataAndSlot, @@ -681,6 +683,27 @@ export class DriftClient { ) as OpenbookV2FulfillmentConfigAccount[]; } + public async getZerofiFulfillmentConfig( + zerofiMarket: PublicKey + ): Promise { + const address = getZerofiFulfillmentConfigPublicKey( + this.program.programId, + zerofiMarket + ); + return (await this.program.account.zerofiFulfillmentConfig.fetch( + address + )) as ZerofiFulfillmentConfigAccount; + } + + public async getZerofiFulfillmentConfigs(): Promise< + ZerofiFulfillmentConfigAccount[] + > { + const accounts = await this.program.account.zerofiFulfillmentConfig.all(); + return accounts.map( + (account) => account.account + ) as ZerofiFulfillmentConfigAccount[]; + } + public async fetchMarketLookupTableAccount(): Promise { if (this.lookupTableAccount) return this.lookupTableAccount; @@ -4218,7 +4241,8 @@ export class DriftClient { fulfillmentConfig?: | SerumV3FulfillmentConfigAccount | PhoenixV1FulfillmentConfigAccount - | OpenbookV2FulfillmentConfigAccount, + | OpenbookV2FulfillmentConfigAccount + | ZerofiFulfillmentConfigAccount, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo, txParams?: TxParams @@ -4248,7 +4272,8 @@ export class DriftClient { fulfillmentConfig?: | SerumV3FulfillmentConfigAccount | PhoenixV1FulfillmentConfigAccount - | OpenbookV2FulfillmentConfigAccount, + | OpenbookV2FulfillmentConfigAccount + | ZerofiFulfillmentConfigAccount, makerInfo?: MakerInfo | MakerInfo[], referrerInfo?: ReferrerInfo, fillerPublicKey?: PublicKey @@ -4328,6 +4353,7 @@ export class DriftClient { | SerumV3FulfillmentConfigAccount | PhoenixV1FulfillmentConfigAccount | OpenbookV2FulfillmentConfigAccount + | ZerofiFulfillmentConfigAccount ): void { if (fulfillmentConfig) { if ('serumProgramId' in fulfillmentConfig) { @@ -4348,6 +4374,12 @@ export class DriftClient { remainingAccounts, fulfillmentConfig ); + } else if ('zerofiProgramId' in fulfillmentConfig) { + this.addZerofiRemainingAccounts( + marketIndex, + remainingAccounts, + fulfillmentConfig + ); } else { throw Error('Invalid fulfillment config type'); } @@ -4610,6 +4642,73 @@ export class DriftClient { } } + addZerofiRemainingAccounts( + marketIndex: number, + remainingAccounts: AccountMeta[], + fulfillmentConfig: ZerofiFulfillmentConfigAccount + ): void { + remainingAccounts.push({ + pubkey: fulfillmentConfig.pubkey, + isWritable: false, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: this.getSignerPublicKey(), + isWritable: true, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: fulfillmentConfig.zerofiProgramId, + isWritable: false, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: fulfillmentConfig.zerofiMarket, + isWritable: true, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: fulfillmentConfig.zerofiVaultBaseInfo, + isWritable: true, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: fulfillmentConfig.zerofiVaultQuoteInfo, + isWritable: true, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: fulfillmentConfig.zerofiVaultBase, + isWritable: true, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: fulfillmentConfig.zerofiVaultQuote, + isWritable: true, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: this.getSpotMarketAccount(marketIndex).vault, + isWritable: true, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: this.getQuoteSpotMarketAccount().vault, + isWritable: true, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: TOKEN_PROGRAM_ID, + isWritable: false, + isSigner: false, + }); + remainingAccounts.push({ + pubkey: SYSVAR_INSTRUCTIONS_PUBKEY, + isWritable: false, + isSigner: false, + }); + } + /** * Swap tokens in drift account using jupiter * @param jupiterClient jupiter client to find routes and jupiter instructions diff --git a/sdk/src/idl/drift.json b/sdk/src/idl/drift.json index 2478883afb..50a0bf6782 100644 --- a/sdk/src/idl/drift.json +++ b/sdk/src/idl/drift.json @@ -3786,6 +3786,95 @@ } ] }, + { + "name": "initializeZerofiFulfillmentConfig", + "accounts": [ + { + "name": "baseSpotMarket", + "isMut": false, + "isSigner": false + }, + { + "name": "quoteSpotMarket", + "isMut": false, + "isSigner": false + }, + { + "name": "state", + "isMut": true, + "isSigner": false + }, + { + "name": "zerofiProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "zerofiMarket", + "isMut": false, + "isSigner": false + }, + { + "name": "driftSigner", + "isMut": false, + "isSigner": false + }, + { + "name": "zerofiFulfillmentConfig", + "isMut": true, + "isSigner": false + }, + { + "name": "admin", + "isMut": true, + "isSigner": true + }, + { + "name": "rent", + "isMut": false, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "marketIndex", + "type": "u16" + } + ] + }, + { + "name": "zerofiFulfillmentConfigStatus", + "accounts": [ + { + "name": "state", + "isMut": false, + "isSigner": false + }, + { + "name": "zerofiFulfillmentConfig", + "isMut": true, + "isSigner": false + }, + { + "name": "admin", + "isMut": true, + "isSigner": true + } + ], + "args": [ + { + "name": "status", + "type": { + "defined": "SpotFulfillmentConfigStatus" + } + } + ] + }, { "name": "updateSerumVault", "accounts": [ @@ -6852,6 +6941,67 @@ ] } }, + { + "name": "ZerofiFulfillmentConfig", + "type": { + "kind": "struct", + "fields": [ + { + "name": "pubkey", + "type": "publicKey" + }, + { + "name": "zerofiProgramId", + "type": "publicKey" + }, + { + "name": "zerofiMarket", + "type": "publicKey" + }, + { + "name": "zerofiVaultBase", + "type": "publicKey" + }, + { + "name": "zerofiVaultBaseInfo", + "type": "publicKey" + }, + { + "name": "zerofiVaultQuote", + "type": "publicKey" + }, + { + "name": "zerofiVaultQuoteInfo", + "type": "publicKey" + }, + { + "name": "marketIndex", + "type": "u16" + }, + { + "name": "fulfillmentType", + "type": { + "defined": "SpotFulfillmentType" + } + }, + { + "name": "status", + "type": { + "defined": "SpotFulfillmentConfigStatus" + } + }, + { + "name": "padding", + "type": { + "array": [ + "u8", + 4 + ] + } + } + ] + } + }, { "name": "HighLeverageModeConfig", "type": { @@ -10770,6 +10920,9 @@ }, { "name": "OpenbookV2" + }, + { + "name": "Zerofi" } ] } @@ -11044,6 +11197,9 @@ }, { "name": "OrderFilledWithOpenbookV2" + }, + { + "name": "OrderFilledWithZerofi" } ] } @@ -14411,6 +14567,21 @@ "code": 6307, "name": "PythLazerMessagePriceFeedMismatch", "msg": "Pyth lazer message does not correspond to correct fed id" + }, + { + "code": 6308, + "name": "FailedZerofiCPI", + "msg": "FailedZerofiCPI" + }, + { + "code": 6309, + "name": "InvalidZerofiProgram", + "msg": "InvalidZerofiProgram" + }, + { + "code": 6310, + "name": "InvalidZerofiMarket", + "msg": "InvalidZerofiMarket" } ], "metadata": { diff --git a/sdk/src/types.ts b/sdk/src/types.ts index 055478e3f6..d5db116dd7 100644 --- a/sdk/src/types.ts +++ b/sdk/src/types.ts @@ -233,6 +233,9 @@ export class OrderActionExplanation { static readonly DERISK_LP = { deriskLp: {}, }; + static readonly ORDER_FILLED_WITH_ZEROFI = { + orderFilledWithZerofi: {}, + }; } export class OrderTriggerCondition { @@ -1319,6 +1322,19 @@ export type OpenbookV2FulfillmentConfigAccount = { remainingAccounts?: PublicKey[]; }; +export type ZerofiFulfillmentConfigAccount = { + pubkey: PublicKey; + zerofiProgramId: PublicKey; + zerofiMarket: PublicKey; + zerofiVaultBase: PublicKey; + zerofiVaultBaseInfo: PublicKey; + zerofiVaultQuote: PublicKey; + zerofiVaultQuoteInfo: PublicKey; + marketIndex: number; + fulfillmentType: SpotFulfillmentType; + status: SpotFulfillmentStatus; +}; + export type ReferrerNameAccount = { name: number[]; user: PublicKey; diff --git a/test-scripts/run-anchor-tests.sh b/test-scripts/run-anchor-tests.sh index ebf7fdadda..44fe68395d 100644 --- a/test-scripts/run-anchor-tests.sh +++ b/test-scripts/run-anchor-tests.sh @@ -82,9 +82,10 @@ test_files=( userDelegate.ts userOrderId.ts whitelist.ts + zerofiTest.ts ) for test_file in ${test_files[@]}; do ts-mocha -t 300000 ./tests/${test_file} || exit 1 -done \ No newline at end of file +done diff --git a/tests/fixtures/zerofi.so b/tests/fixtures/zerofi.so new file mode 100755 index 0000000000..fde211ef99 Binary files /dev/null and b/tests/fixtures/zerofi.so differ diff --git a/tests/fixtures/zerofi/market-G6Yn5VpiUbySimawqXEveD3RdTVsf7FzSgAJK3EABAjZ.json b/tests/fixtures/zerofi/market-G6Yn5VpiUbySimawqXEveD3RdTVsf7FzSgAJK3EABAjZ.json new file mode 100644 index 0000000000..1a15ef1788 --- /dev/null +++ b/tests/fixtures/zerofi/market-G6Yn5VpiUbySimawqXEveD3RdTVsf7FzSgAJK3EABAjZ.json @@ -0,0 +1 @@ +{"lamports":52784640,"data":[4,0,0,0,0,0,0,0,25,59,145,91,242,87,44,194,216,238,152,135,16,60,226,109,208,37,226,45,24,48,231,73,106,206,5,175,133,51,185,229,25,59,145,91,242,87,44,194,216,238,152,135,16,60,226,109,208,37,226,45,24,48,231,73,106,206,5,175,133,51,185,229,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,203,195,255,168,172,196,137,173,7,198,187,63,9,243,210,107,139,5,134,164,241,208,82,86,177,185,92,151,68,79,192,56,112,153,220,90,44,221,79,179,41,212,227,248,77,134,81,94,140,111,76,109,187,219,136,211,45,90,129,182,64,54,145,124,199,145,50,131,73,180,100,81,19,213,231,97,170,85,153,134,74,188,170,89,105,252,191,135,119,38,193,154,174,37,139,58,227,141,173,159,105,183,217,250,249,177,76,244,141,92,67,44,213,42,121,48,163,172,206,98,215,147,255,179,170,161,110,211,255,255,6,6,0,0,0,0,0,228,11,84,2,0,0,0,255,255,255,255,255,255,255,255,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,232,3,0,0,0,0,0,0,232,3,0,0,0,0,0,0,232,3,0,0,0,0,0,0,232,3,0,0,0,0,0,0,232,3,0,0,0,0,0,0,232,3,0,0,0,0,0,0,232,3,0,0,0,0,0,0,232,3,0,0,0,0,0,0,232,3,0,0,0,0,0,0,232,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,63,0,0,0,0,0,0,89,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,64,123,20,174,71,225,122,132,63,0,0,0,0,0,0,240,63,123,20,174,71,225,122,132,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,232,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,228,11,84,2,0,0,0,0,228,11,84,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,228,11,84,2,0,0,0,0,228,11,84,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"owner":[8,65,196,198,238,55,111,23,202,75,3,26,148,248,184,42,106,178,174,145,174,25,224,140,116,54,106,121,117,145,8,151],"executable":false,"rentEpoch":18446744073709551615} \ No newline at end of file diff --git a/tests/fixtures/zerofi/mint_base-1111111QLbz7JHiBTspS962RLKV8GndWFwiEaqKM.json b/tests/fixtures/zerofi/mint_base-1111111QLbz7JHiBTspS962RLKV8GndWFwiEaqKM.json new file mode 100644 index 0000000000..3498481f48 --- /dev/null +++ b/tests/fixtures/zerofi/mint_base-1111111QLbz7JHiBTspS962RLKV8GndWFwiEaqKM.json @@ -0,0 +1 @@ +{"lamports":1,"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"owner":[6,221,246,225,215,101,161,147,217,203,225,70,206,235,121,172,28,180,133,237,95,91,55,145,58,140,245,133,126,255,0,169],"executable":false,"rentEpoch":0} \ No newline at end of file diff --git a/tests/fixtures/zerofi/mint_quote-1111111ogCyDbaRMvkdsHB3qfdyFYaG1WtRUAfdh.json b/tests/fixtures/zerofi/mint_quote-1111111ogCyDbaRMvkdsHB3qfdyFYaG1WtRUAfdh.json new file mode 100644 index 0000000000..3498481f48 --- /dev/null +++ b/tests/fixtures/zerofi/mint_quote-1111111ogCyDbaRMvkdsHB3qfdyFYaG1WtRUAfdh.json @@ -0,0 +1 @@ +{"lamports":1,"data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"owner":[6,221,246,225,215,101,161,147,217,203,225,70,206,235,121,172,28,180,133,237,95,91,55,145,58,140,245,133,126,255,0,169],"executable":false,"rentEpoch":0} \ No newline at end of file diff --git a/tests/fixtures/zerofi/user_authority-DiCEXQfxHqfY7D4JHU3fbmvWmTV26F2DQzsoCySpE1Ya.json b/tests/fixtures/zerofi/user_authority-DiCEXQfxHqfY7D4JHU3fbmvWmTV26F2DQzsoCySpE1Ya.json new file mode 100644 index 0000000000..bbece8f5ed --- /dev/null +++ b/tests/fixtures/zerofi/user_authority-DiCEXQfxHqfY7D4JHU3fbmvWmTV26F2DQzsoCySpE1Ya.json @@ -0,0 +1 @@ +{"lamports":1000000000,"data":[],"owner":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"executable":false,"rentEpoch":0} \ No newline at end of file diff --git a/tests/fixtures/zerofi/user_base-11111112D1oxKts8YPdTJRG5FzxTNpMtWmq8hkVx3.json b/tests/fixtures/zerofi/user_base-11111112D1oxKts8YPdTJRG5FzxTNpMtWmq8hkVx3.json new file mode 100644 index 0000000000..5b6a75ad01 --- /dev/null +++ b/tests/fixtures/zerofi/user_base-11111112D1oxKts8YPdTJRG5FzxTNpMtWmq8hkVx3.json @@ -0,0 +1 @@ +{"lamports":1,"data":[0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,188,217,193,247,119,18,116,71,248,24,163,105,206,248,36,245,96,188,54,17,31,160,41,119,236,211,196,51,200,174,173,63,0,202,154,59,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"owner":[6,221,246,225,215,101,161,147,217,203,225,70,206,235,121,172,28,180,133,237,95,91,55,145,58,140,245,133,126,255,0,169],"executable":false,"rentEpoch":0} \ No newline at end of file diff --git a/tests/fixtures/zerofi/user_quote-11111112cMQwSC9qirWGjZM6gLGwW69X22mqwLLGP.json b/tests/fixtures/zerofi/user_quote-11111112cMQwSC9qirWGjZM6gLGwW69X22mqwLLGP.json new file mode 100644 index 0000000000..de90f030d2 --- /dev/null +++ b/tests/fixtures/zerofi/user_quote-11111112cMQwSC9qirWGjZM6gLGwW69X22mqwLLGP.json @@ -0,0 +1 @@ +{"lamports":1,"data":[0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,188,217,193,247,119,18,116,71,248,24,163,105,206,248,36,245,96,188,54,17,31,160,41,119,236,211,196,51,200,174,173,63,0,202,154,59,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"owner":[6,221,246,225,215,101,161,147,217,203,225,70,206,235,121,172,28,180,133,237,95,91,55,145,58,140,245,133,126,255,0,169],"executable":false,"rentEpoch":0} \ No newline at end of file diff --git a/tests/fixtures/zerofi/vault_base-EiR75kaWP1CUvLMuwVSg1KKcjp9YJxifbQBnQt74SFKM.json b/tests/fixtures/zerofi/vault_base-EiR75kaWP1CUvLMuwVSg1KKcjp9YJxifbQBnQt74SFKM.json new file mode 100644 index 0000000000..70de9910ec --- /dev/null +++ b/tests/fixtures/zerofi/vault_base-EiR75kaWP1CUvLMuwVSg1KKcjp9YJxifbQBnQt74SFKM.json @@ -0,0 +1 @@ +{"lamports":2039280,"data":[0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,203,195,255,168,172,196,137,173,7,198,187,63,9,243,210,107,139,5,134,164,241,208,82,86,177,185,92,151,68,79,192,56,0,202,154,59,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"owner":[6,221,246,225,215,101,161,147,217,203,225,70,206,235,121,172,28,180,133,237,95,91,55,145,58,140,245,133,126,255,0,169],"executable":false,"rentEpoch":18446744073709551615} \ No newline at end of file diff --git a/tests/fixtures/zerofi/vault_base_info-8aYjmYBJnwo1G9VSCfYPZDsmnnsLpPwoqpTvwuoV3TTZ.json b/tests/fixtures/zerofi/vault_base_info-8aYjmYBJnwo1G9VSCfYPZDsmnnsLpPwoqpTvwuoV3TTZ.json new file mode 100644 index 0000000000..965dc2c27e --- /dev/null +++ b/tests/fixtures/zerofi/vault_base_info-8aYjmYBJnwo1G9VSCfYPZDsmnnsLpPwoqpTvwuoV3TTZ.json @@ -0,0 +1 @@ +{"lamports":8352000,"data":[1,0,0,0,0,0,0,0,25,59,145,91,242,87,44,194,216,238,152,135,16,60,226,109,208,37,226,45,24,48,231,73,106,206,5,175,133,51,185,229,203,195,255,168,172,196,137,173,7,198,187,63,9,243,210,107,139,5,134,164,241,208,82,86,177,185,92,151,68,79,192,56,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,112,153,220,90,44,221,79,179,41,212,227,248,77,134,81,94,140,111,76,109,187,219,136,211,45,90,129,182,64,54,145,124,0,148,53,119,0,0,0,0,255,255,255,255,255,255,255,255,0,202,154,59,0,0,0,0,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,148,53,119,0,0,0,0,0,202,154,59,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,202,154,59,0,0,0,0,0,0,0,0,255,1,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"owner":[8,65,196,198,238,55,111,23,202,75,3,26,148,248,184,42,106,178,174,145,174,25,224,140,116,54,106,121,117,145,8,151],"executable":false,"rentEpoch":18446744073709551615} \ No newline at end of file diff --git a/tests/fixtures/zerofi/vault_quote-ES2YchtvBNn91Q8TWHfGhwqX5VdbhMmfujPRmkoRXPVT.json b/tests/fixtures/zerofi/vault_quote-ES2YchtvBNn91Q8TWHfGhwqX5VdbhMmfujPRmkoRXPVT.json new file mode 100644 index 0000000000..7d28fd52c2 --- /dev/null +++ b/tests/fixtures/zerofi/vault_quote-ES2YchtvBNn91Q8TWHfGhwqX5VdbhMmfujPRmkoRXPVT.json @@ -0,0 +1 @@ +{"lamports":2039280,"data":[0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,199,145,50,131,73,180,100,81,19,213,231,97,170,85,153,134,74,188,170,89,105,252,191,135,119,38,193,154,174,37,139,58,0,202,154,59,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"owner":[6,221,246,225,215,101,161,147,217,203,225,70,206,235,121,172,28,180,133,237,95,91,55,145,58,140,245,133,126,255,0,169],"executable":false,"rentEpoch":18446744073709551615} \ No newline at end of file diff --git a/tests/fixtures/zerofi/vault_quote_info-GKGrCkr12UQCQ4RPt1NyziyCqjuMLkn9JmtQrReZTzAN.json b/tests/fixtures/zerofi/vault_quote_info-GKGrCkr12UQCQ4RPt1NyziyCqjuMLkn9JmtQrReZTzAN.json new file mode 100644 index 0000000000..3a5f9c2b96 --- /dev/null +++ b/tests/fixtures/zerofi/vault_quote_info-GKGrCkr12UQCQ4RPt1NyziyCqjuMLkn9JmtQrReZTzAN.json @@ -0,0 +1 @@ +{"lamports":8352000,"data":[1,0,0,0,0,0,0,0,25,59,145,91,242,87,44,194,216,238,152,135,16,60,226,109,208,37,226,45,24,48,231,73,106,206,5,175,133,51,185,229,199,145,50,131,73,180,100,81,19,213,231,97,170,85,153,134,74,188,170,89,105,252,191,135,119,38,193,154,174,37,139,58,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,227,141,173,159,105,183,217,250,249,177,76,244,141,92,67,44,213,42,121,48,163,172,206,98,215,147,255,179,170,161,110,211,0,148,53,119,0,0,0,0,255,255,255,255,255,255,255,255,0,202,154,59,0,0,0,0,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,148,53,119,0,0,0,0,0,202,154,59,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,202,154,59,0,0,0,0,0,0,0,0,255,1,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"owner":[8,65,196,198,238,55,111,23,202,75,3,26,148,248,184,42,106,178,174,145,174,25,224,140,116,54,106,121,117,145,8,151],"executable":false,"rentEpoch":18446744073709551615} \ No newline at end of file diff --git a/tests/zerofiTest.ts b/tests/zerofiTest.ts new file mode 100644 index 0000000000..73b7a153ce --- /dev/null +++ b/tests/zerofiTest.ts @@ -0,0 +1,340 @@ +import { assert } from 'chai'; +import * as anchor from '@coral-xyz/anchor'; + +import { Program, BN } from '@coral-xyz/anchor'; + +import { + OracleSource, + OrderType, + PositionDirection, + PublicKey, + TestClient, +} from '../sdk/src'; +import { startAnchor, AddedAccount } from 'solana-bankrun'; +import { TestBulkAccountLoader } from '../sdk/src/accounts/testBulkAccountLoader'; +import { BankrunContextWrapper } from '../sdk/src/bankrun/bankrunConnection'; +import { + initializeQuoteSpotMarket, + initializeSolSpotMarket, + mockOracleNoProgram, +} from './testHelpers'; +import { Keypair } from '@solana/web3.js'; +import { PRICE_PRECISION } from '../sdk/src'; +import { ZERO } from '../sdk'; +import fs from 'fs'; +import path from 'path'; +import { globSync } from 'glob'; +import bs58 from 'bs58'; + +export const ZEROFI_PROGRAM = new PublicKey( + 'ZERor4xhbUycZ6gb9ntrhqscUcZmAbQDjEAtCf4hbZY' +); + +interface AccountFile { + lamports: number; + data: number[]; + owner: number[]; + executable: boolean; + rentEpoch: number; +} + +interface ParsedAccounts { + accounts: AddedAccount[]; + nameToKey: Map; +} + +function loadFixtureAccounts(fixturesPath: string): ParsedAccounts { + const files = globSync(path.join(fixturesPath, '*.json')); + + const accounts: AddedAccount[] = []; + const nameToKey = new Map(); + + const filenamePattern = /^([^-]+)-([A-Za-z0-9]{32,44})\.json$/; + + for (const file of files) { + const basename = path.basename(file); + const match = basename.match(filenamePattern); + if (!match) { + continue; + } + + const [, name, pubkeyStr] = match; + + let pubkey: PublicKey; + try { + pubkey = new PublicKey(pubkeyStr); + } catch (e) { + console.warn(`Skipping ${file}: invalid pubkey`); + continue; + } + + try { + const content = fs.readFileSync(file, 'utf8'); + const accountData = JSON.parse(content) as AccountFile; + + const account = { + address: pubkey, + info: { + lamports: accountData.lamports, + data: Uint8Array.from(accountData.data), + owner: new PublicKey(Buffer.from(accountData.owner)), + executable: accountData.executable, + rentEpoch: accountData.rentEpoch, + }, + }; + + accounts.push(account); + nameToKey.set(name, pubkey); + } catch (e) { + console.warn(`Error processing ${file}: ${e}`); + continue; + } + } + + return { accounts, nameToKey }; +} + +describe('zerofi', () => { + const chProgram = anchor.workspace.Drift as Program; + + let driftClient: TestClient; + + let fillerDriftClient: TestClient; + const fillerKeypair = Keypair.generate(); + + let bulkAccountLoader: TestBulkAccountLoader; + + let bankrunContextWrapper: BankrunContextWrapper; + + const solSpotMarketIndex = 1; + + let usdcMint: PublicKey; + let solMint: PublicKey; + + const usdcAmount = new anchor.BN(200 * 10 ** 6); + + let userUsdcAccount: PublicKey; + + let market: PublicKey; + + before(async () => { + const { accounts: fixtureAccountList, nameToKey: fixtureAccountsByName } = + loadFixtureAccounts('tests/fixtures/zerofi'); + console.log(fixtureAccountsByName); + + const context = await startAnchor( + '', + [ + { + name: 'zerofi', + programId: ZEROFI_PROGRAM, + }, + ], + fixtureAccountList + ); + + bankrunContextWrapper = new BankrunContextWrapper(context); + + // override the wallet to be the one that's shared + const keypair = Keypair.fromSecretKey( + bs58.decode( + '4ruNgnB26rEiy9G1nBevajsjkeoUNzjVWkdrcFnQ8BKyrF2ZYQ21gDfFsfrZmXU4FkbCjQVAktkMCnoAQeyBYrYW' + ) + ); + const wallet = new anchor.Wallet(keypair); + bankrunContextWrapper.provider.wallet = wallet; + + bulkAccountLoader = new TestBulkAccountLoader( + bankrunContextWrapper.connection, + 'processed', + 1 + ); + + const solOracle = await mockOracleNoProgram(bankrunContextWrapper, 100); + + usdcMint = fixtureAccountsByName.get('mint_quote'); + solMint = fixtureAccountsByName.get('mint_base'); + userUsdcAccount = fixtureAccountsByName.get('user_quote'); + market = fixtureAccountsByName.get('market'); + + driftClient = new TestClient({ + connection: bankrunContextWrapper.connection.toConnection(), + wallet: bankrunContextWrapper.provider.wallet, + programID: chProgram.programId, + opts: { + commitment: 'confirmed', + }, + activeSubAccountId: 0, + perpMarketIndexes: [0], + spotMarketIndexes: [0, 1], + subAccountIds: [], + oracleInfos: [ + { + publicKey: solOracle, + source: OracleSource.PYTH, + }, + ], + userStats: true, + accountSubscription: { + type: 'polling', + accountLoader: bulkAccountLoader, + }, + }); + + await driftClient.initialize(usdcMint, true); + await driftClient.subscribe(); + + await initializeQuoteSpotMarket(driftClient, usdcMint); + await initializeSolSpotMarket(driftClient, solOracle, solMint); + + const quoteSizeLot = new BN(1); + const baseSizeLot = new BN(100); + await driftClient.updateSpotMarketStepSizeAndTickSize( + 1, + baseSizeLot, + quoteSizeLot + ); + + await driftClient.updateSpotMarketOrdersEnabled(1, true); + + await driftClient.initializeUserAccountAndDepositCollateral( + // @ts-ignore + usdcAmount, + userUsdcAccount + ); + + await driftClient.addUser(0); + // @ts-ignore + // await driftClient.deposit(solAmount, 1, userWSolAccount.publicKey); + + fillerDriftClient = new TestClient({ + connection: bankrunContextWrapper.connection.toConnection(), + wallet: new anchor.Wallet(fillerKeypair), + programID: chProgram.programId, + opts: { + commitment: 'confirmed', + }, + activeSubAccountId: 0, + perpMarketIndexes: [0], + spotMarketIndexes: [0, 1], + subAccountIds: [], + oracleInfos: [ + { + publicKey: solOracle, + source: OracleSource.PYTH, + }, + ], + userStats: true, + accountSubscription: { + type: 'polling', + accountLoader: bulkAccountLoader, + }, + }); + + await fillerDriftClient.subscribe(); + + await bankrunContextWrapper.fundKeypair(fillerKeypair, 10 * 10 ** 9); + + await fillerDriftClient.initializeUserAccount(); + + await fillerDriftClient.addUser(0); + }); + + after(async () => { + await driftClient.unsubscribe(); + await fillerDriftClient.unsubscribe(); + }); + + it('add market', async () => { + await driftClient.initializeZerofiFulfillmentConfig( + solSpotMarketIndex, + market + ); + }); + + it('fill long', async () => { + const quoteTokenAmountBefore = driftClient.getTokenAmount(0); + const baseTokenAmountBefore = driftClient.getTokenAmount(1); + + console.log(`quoteTokenAmountBefore ${quoteTokenAmountBefore.toString()}`); + console.log(`baseTokenAmountBefore ${baseTokenAmountBefore.toString()}`); + + await driftClient.placeSpotOrder({ + orderType: OrderType.LIMIT, + marketIndex: 1, + // @ts-ignore + baseAssetAmount: driftClient.convertToSpotPrecision(1, 1), + direction: PositionDirection.LONG, + price: PRICE_PRECISION.muln(101), + }); + + const fulfillmentConfig = await driftClient.getZerofiFulfillmentConfig( + market + ); + + const userAccount = driftClient.getUserAccount(); + const order = userAccount.orders.filter( + (order) => order.marketIndex == 1 + )[0]; + await fillerDriftClient.fillSpotOrder( + await driftClient.getUserAccountPublicKey(), + driftClient.getUserAccount(), + order, + fulfillmentConfig + ); + + await driftClient.fetchAccounts(); + + const quoteTokenAmountAfter = driftClient.getTokenAmount(0); + const baseTokenAmountAfter = driftClient.getTokenAmount(1); + + console.log(`quoteTokenAmountAfter ${quoteTokenAmountAfter.toString()}`); + console.log(`baseTokenAmountAfter ${baseTokenAmountAfter.toString()}`); + + assert(baseTokenAmountAfter.eq(new BN(1e6))); + // cost is 101 + 0.1% drift fee + assert(quoteTokenAmountAfter.eq(new BN(200e6 - 101.101001e6))); + }); + + it('fill short', async () => { + const quoteTokenAmountBefore = driftClient.getTokenAmount(0); + + await driftClient.placeSpotOrder({ + orderType: OrderType.LIMIT, + marketIndex: 1, + // @ts-ignore + baseAssetAmount: driftClient.convertToSpotPrecision(1, 1), + direction: PositionDirection.SHORT, + price: PRICE_PRECISION.muln(99), + }); + + const fulfillmentConfig = await driftClient.getZerofiFulfillmentConfig( + market + ); + + const userAccount = driftClient.getUserAccount(); + const order = userAccount.orders.filter( + (order) => order.marketIndex == 1 + )[0]; + await fillerDriftClient.fillSpotOrder( + await driftClient.getUserAccountPublicKey(), + driftClient.getUserAccount(), + order, + fulfillmentConfig + ); + + await driftClient.fetchAccounts(); + + const quoteTokenAmountAfter = driftClient.getTokenAmount(0); + const baseTokenAmountAfter = driftClient.getTokenAmount(1); + + console.log(`quoteTokenAmountAfter ${quoteTokenAmountAfter.toString()}`); + console.log(`baseTokenAmountAfter ${baseTokenAmountAfter.toString()}`); + + assert(baseTokenAmountAfter.eq(ZERO)); + // 99 - 0.1% drift fee + assert( + quoteTokenAmountAfter.eq(quoteTokenAmountBefore.add(new BN(98.901e6))) + ); + }); +}); diff --git a/yarn.lock b/yarn.lock index 3238694fb3..ca886d47ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -176,6 +176,18 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + "@js-sdsl/ordered-map@^4.4.2": version "4.4.2" resolved "https://registry.yarnpkg.com/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz#9299f82874bab9e4c7f9c48d865becbfe8d6907c" @@ -286,6 +298,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + "@project-serum/anchor@^0.11.1": version "0.11.1" resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.11.1.tgz#155bff2c70652eafdcfd5559c81a83bb19cec9ff" @@ -724,11 +741,29 @@ dependencies: "@types/node" "*" +"@types/glob@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-8.1.0.tgz#b63e70155391b0584dce44e7ea25190bbc38f2fc" + integrity sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w== + dependencies: + "@types/minimatch" "^5.1.2" + "@types/node" "*" + "@types/json-schema@^7.0.7": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + +"@types/minimatch@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" + integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== + "@types/mocha@8.2.3": version "8.2.3" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.3.tgz#bbeb55fbc73f28ea6de601fbfa4613f58d785323" @@ -921,7 +956,7 @@ anchor-bankrun@0.3.0: resolved "https://registry.yarnpkg.com/anchor-bankrun/-/anchor-bankrun-0.3.0.tgz#3789fcecbc201a2334cff228b99cc0da8ef0167e" integrity sha512-PYBW5fWX+iGicIS5MIM/omhk1tQPUc0ELAnI/IkLKQJ6d75De/CQRh8MF2bU/TgGyFi6zEel80wUe3uRol9RrQ== -ansi-colors@^4.1.1: +ansi-colors@^4.1.1, ansi-colors@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== @@ -931,6 +966,11 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-regex@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" + integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== + ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -945,11 +985,24 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + ansicolors@^0.3.2, ansicolors@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" integrity sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg== +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -967,6 +1020,11 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== + assert@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/assert/-/assert-2.1.0.tgz#6d92a238d05dc02e7427c881fb8be81c8448b2dd" @@ -1043,6 +1101,11 @@ base-x@^4.0.0: resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a" integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw== +base-x@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-5.0.0.tgz#6d835ceae379130e1a4cb846a70ac4746f28ea9b" + integrity sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ== + base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" @@ -1065,6 +1128,11 @@ bignumber.js@^9.0.1: resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== +binary-extensions@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== + bindings@^1.3.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" @@ -1106,13 +1174,18 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^3.0.3: +braces@^3.0.3, braces@~3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: fill-range "^7.1.1" +browser-stdout@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + bs58@^4.0.0, bs58@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" @@ -1127,6 +1200,18 @@ bs58@^5.0.0: dependencies: base-x "^4.0.0" +bs58@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-6.0.0.tgz#a2cda0130558535dd281a2f8697df79caaf425d8" + integrity sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw== + dependencies: + base-x "^5.0.0" + +buffer-from@^1.0.0, buffer-from@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + buffer-layout@^1.2.0, buffer-layout@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/buffer-layout/-/buffer-layout-1.2.2.tgz#b9814e7c7235783085f9ca4966a0cfff112259d5" @@ -1176,7 +1261,7 @@ camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.2.1, camelcase@^6.3.0: +camelcase@^6.0.0, camelcase@^6.2.1, camelcase@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== @@ -1208,7 +1293,7 @@ chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0: +chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -1228,6 +1313,30 @@ check-error@^1.0.3: dependencies: get-func-name "^2.0.2" +chokidar@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + cliui@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" @@ -1310,6 +1419,15 @@ cross-fetch@^3.1.5: dependencies: node-fetch "^2.6.12" +cross-spawn@^7.0.0: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + cross-spawn@^7.0.2: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -1340,6 +1458,18 @@ debug@^4.0.1, debug@^4.1.1, debug@^4.3.1, debug@^4.3.3, debug@^4.3.4: dependencies: ms "2.1.2" +debug@^4.3.5: + version "4.4.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" + integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== + dependencies: + ms "^2.1.3" + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + decimal.js@^10.4.0, decimal.js@^10.4.3: version "10.4.3" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" @@ -1385,6 +1515,16 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== +diff@^3.1.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +diff@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" + integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -1417,11 +1557,21 @@ dotenv@16.4.5, dotenv@^16.0.3: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + enquirer@^2.3.5: version "2.4.1" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" @@ -1688,6 +1838,14 @@ find-process@^1.4.7: commander "^5.1.0" debug "^4.1.1" +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + find@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/find/-/find-0.3.0.tgz#4082e8fc8d8320f1a382b5e4f521b9bc50775cb8" @@ -1704,6 +1862,11 @@ flat-cache@^3.0.4: keyv "^4.5.3" rimraf "^3.0.2" +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + flatted@^3.2.9: version "3.3.1" resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" @@ -1721,6 +1884,14 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" +foreground-child@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77" + integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -1735,6 +1906,11 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + function-bind@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" @@ -1766,13 +1942,37 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: has-symbols "^1.0.3" hasown "^2.0.0" -glob-parent@^5.1.2: +glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" +glob@^10.4.5: + version "10.4.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" + integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== + dependencies: + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" + +glob@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-11.0.0.tgz#6031df0d7b65eaa1ccb9b29b5ced16cea658e77e" + integrity sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^4.0.1" + minimatch "^10.0.0" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^2.0.0" + glob@^7.1.3: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -1852,6 +2052,11 @@ hasown@^2.0.0: dependencies: function-bind "^1.1.2" +he@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + humanize-ms@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" @@ -1913,6 +2118,13 @@ is-arguments@^1.0.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-callable@^1.1.3: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" @@ -1935,7 +2147,7 @@ is-generator-function@^1.0.7: dependencies: has-tostringtag "^1.0.0" -is-glob@^4.0.0, is-glob@^4.0.1: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -1955,6 +2167,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + is-retry-allowed@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz#88f34cbd236e043e71b6932d09b0c65fb7b4d71d" @@ -1967,6 +2184,11 @@ is-typed-array@^1.1.3: dependencies: which-typed-array "^1.1.14" +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" @@ -1982,6 +2204,22 @@ isomorphic-ws@^4.0.1: resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== +jackspeak@^3.1.2: + version "3.4.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" + integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +jackspeak@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.0.2.tgz#11f9468a3730c6ff6f56823a820d7e3be9bef015" + integrity sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw== + dependencies: + "@isaacs/cliui" "^8.0.2" + jayson@^3.4.4: version "3.7.0" resolved "https://registry.yarnpkg.com/jayson/-/jayson-3.7.0.tgz#b735b12d06d348639ae8230d7a1e2916cb078f25" @@ -2110,6 +2348,13 @@ json2csv@5.0.7: jsonparse "^1.3.1" lodash.get "^4.4.2" +json5@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== + dependencies: + minimist "^1.2.0" + jsonc-parser@^3.0.0: version "3.2.1" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.1.tgz#031904571ccf929d7670ee8c547545081cb37f1a" @@ -2140,6 +2385,13 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" @@ -2165,6 +2417,14 @@ lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.3: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +log-symbols@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + long@^5.0.0: version "5.2.3" resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" @@ -2184,11 +2444,26 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" +lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + +lru-cache@^11.0.0: + version "11.0.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.0.2.tgz#fbd8e7cf8211f5e7e5d91905c415a3f55755ca39" + integrity sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA== + lunr@^2.3.9: version "2.3.9" resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + marked@^4.2.4: version "4.3.0" resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3" @@ -2219,6 +2494,13 @@ mime-types@^2.1.12: dependencies: mime-db "1.52.0" +minimatch@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.1.tgz#ce0521856b453c86e25f2c4c0d03e6ff7ddc440b" + integrity sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ== + dependencies: + brace-expansion "^2.0.1" + minimatch@^3.0.4, minimatch@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -2226,19 +2508,69 @@ minimatch@^3.0.4, minimatch@^3.1.1: dependencies: brace-expansion "^1.1.7" -minimatch@^5.1.1: +minimatch@^5.1.1, minimatch@^5.1.6: version "5.1.6" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== dependencies: brace-expansion "^2.0.1" +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.0, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== + +mkdirp@^0.5.1: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mocha@^11.0.1: + version "11.0.1" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-11.0.1.tgz#85c1c0e806275fe2479245be4ac4a0d81f533aa8" + integrity sha512-+3GkODfsDG71KSCQhc4IekSW+ItCK/kiez1Z28ksWvYhKXV/syxMlerR/sC7whDp7IyreZ4YxceMLdTs5hQE8A== + dependencies: + ansi-colors "^4.1.3" + browser-stdout "^1.3.1" + chokidar "^3.5.3" + debug "^4.3.5" + diff "^5.2.0" + escape-string-regexp "^4.0.0" + find-up "^5.0.0" + glob "^10.4.5" + he "^1.2.0" + js-yaml "^4.1.0" + log-symbols "^4.1.0" + minimatch "^5.1.6" + ms "^2.1.3" + serialize-javascript "^6.0.2" + strip-json-comments "^3.1.1" + supports-color "^8.1.1" + workerpool "^6.5.1" + yargs "^16.2.0" + yargs-parser "^20.2.9" + yargs-unparser "^2.0.0" + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.0.0: +ms@^2.0.0, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -2280,6 +2612,11 @@ node-gyp-build@^4.3.0: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.1.tgz#976d3ad905e71b76086f4f0b0d3637fe79b6cda5" integrity sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw== +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + object-is@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.6.tgz#1a6a53aed2dd8f7e6775ff870bea58545956ab07" @@ -2322,6 +2659,25 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.5" +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +package-json-from-dist@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== + pako@^2.0.3: version "2.1.0" resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" @@ -2334,6 +2690,11 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -2344,6 +2705,22 @@ path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-scurry@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +path-scurry@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.0.tgz#9f052289f23ad8bf9397a2a0425e7b8615c58580" + integrity sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg== + dependencies: + lru-cache "^11.0.0" + minipass "^7.1.2" + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -2359,7 +2736,7 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== -picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -2429,6 +2806,20 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + regenerator-runtime@^0.14.0: version "0.14.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" @@ -2514,7 +2905,7 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -safe-buffer@^5.0.1: +safe-buffer@^5.0.1, safe-buffer@^5.1.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -2524,6 +2915,13 @@ semver@^7.2.1, semver@^7.3.5, semver@^7.3.7: resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== +serialize-javascript@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== + dependencies: + randombytes "^2.1.0" + set-function-length@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" @@ -2557,6 +2955,11 @@ shiki@^0.11.1: vscode-oniguruma "^1.6.1" vscode-textmate "^6.0.0" +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -2618,6 +3021,19 @@ solana-bankrun@0.3.0: solana-bankrun-linux-x64-gnu "0.3.0" solana-bankrun-linux-x64-musl "0.3.0" +source-map-support@^0.5.6: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + spok@^1.4.3: version "1.5.5" resolved "https://registry.yarnpkg.com/spok/-/spok-1.5.5.tgz#a51f7f290a53131d7b7a922dfedc461dda0aed72" @@ -2631,6 +3047,15 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" @@ -2640,6 +3065,22 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -2647,6 +3088,13 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + strip-bom@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" @@ -2654,6 +3102,11 @@ strip-bom@^2.0.0: dependencies: is-utf8 "^0.2.0" +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" @@ -2701,6 +3154,13 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + table@^6.0.9: version "6.8.2" resolved "https://registry.yarnpkg.com/table/-/table-6.8.2.tgz#c5504ccf201213fa227248bdc8c5569716ac6c58" @@ -2759,6 +3219,39 @@ ts-log@^2.2.4: resolved "https://registry.yarnpkg.com/ts-log/-/ts-log-2.2.7.tgz#4f4512144898b77c9984e91587076fcb8518688e" integrity sha512-320x5Ggei84AxzlXp91QkIGSw5wgaLT6GeAH0KsqDmRZdVWW2OiSeVvElVoatk3f7nicwXlElXsoFkARiGE2yg== +ts-mocha@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-10.0.0.tgz#41a8d099ac90dbbc64b06976c5025ffaebc53cb9" + integrity sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw== + dependencies: + ts-node "7.0.1" + optionalDependencies: + tsconfig-paths "^3.5.0" + +ts-node@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf" + integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== + dependencies: + arrify "^1.0.0" + buffer-from "^1.1.0" + diff "^3.1.0" + make-error "^1.1.1" + minimist "^1.2.0" + mkdirp "^0.5.1" + source-map-support "^0.5.6" + yn "^2.0.0" + +tsconfig-paths@^3.5.0: + version "3.15.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" + integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + tslib@^1.8.1: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" @@ -2894,6 +3387,20 @@ word-wrap@^1.2.5: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== +workerpool@^6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544" + integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -2903,6 +3410,15 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -2928,11 +3444,39 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yargs-parser@^20.2.2, yargs-parser@^20.2.9: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== +yargs-unparser@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + yargs@^17.7.2: version "17.7.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" @@ -2946,6 +3490,16 @@ yargs@^17.7.2: y18n "^5.0.5" yargs-parser "^21.1.1" +yn@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" + integrity sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + zstddec@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/zstddec/-/zstddec-0.1.0.tgz#7050f3f0e0c3978562d0c566b3e5a427d2bad7ec"